package com.example.glgk.service.gather;

import com.example.glgk.dto.EscalationData;
import com.example.glgk.dto.QueryEscalation;
import com.example.glgk.entity.DepartmentIndicatorEntity;
import com.example.glgk.entity.ElementDataEntity;
import com.example.glgk.entity.IndicatorDataEntity;
import com.example.glgk.mapper.ElementDataDayMapper;
import com.example.glgk.mapper.ElementDataMapper;
import com.example.glgk.mapper.ElementDataMonthMapper;
import com.example.glgk.mapper.IndicatorDataMapper;
import com.example.glgk.utils.CalculatorUtils;
import com.example.glgk.utils.ExcelUtils;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lxk
 */
@Service
@Slf4j
public class DataGatherService {

    @Autowired
    IndicatorDataMapper indicatorDataMapper;

    @Autowired
    ElementDataMapper elementDataMapper;

    @Autowired
    ElementDataDayMapper elementDataDayMapper;

    @Autowired
    ElementDataMonthMapper elementDataMonthMapper;

    @Autowired
    GatherCommonService gatherCommonService;


    public List<EscalationData> queryDataGather(QueryEscalation queryEscalation) {
        PageHelper.startPage(queryEscalation.getPageNumber(), queryEscalation.getPageSize());
        return queryData(queryEscalation);
    }

    private List<EscalationData> queryData(QueryEscalation queryEscalation) {
        List<String> times = queryEscalation.getTimes();
        String s1 = times.get(0);
        queryEscalation.setAllTimes(times);
        List<EscalationData> result = new ArrayList<>();
        //查询指标表中的所有的关于上报信息的元素定义公式 todo 后续查询where条件补充，只查询指标上报
        List<IndicatorDataEntity> list = indicatorDataMapper.selectAll(queryEscalation);
        //todo 分页插件超过最后一页了，结果还是会默认查询最后一页，先暂时这样 这里是分页插件的问题，后续有空看怎么改合适
        List<IndicatorDataEntity> count = indicatorDataMapper.selectAll(queryEscalation);
        if (count.size() <  (queryEscalation.getPageSize() * queryEscalation.getPageNumber())) {
            return null;
        }
        List<String> elementIds = gatherCommonService.getAllElementIds(list);
        //查询元素定义表，确定元素数据来源
        List<ElementDataEntity> elementDataEntities = elementDataMapper.query(elementIds);
        //分别得出天表，月表，手填表的元素数据
        List<ElementDataEntity> dayTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "1".equals(s.getDataTable())).collect(Collectors.toList());
        List<ElementDataEntity> monthTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "2".equals(s.getDataTable())).collect(Collectors.toList());
        List<ElementDataEntity> handTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "3".equals(s.getDataTable())).collect(Collectors.toList());

        List<DepartmentIndicatorEntity> dayData = new ArrayList<>();
        if (!org.springframework.util.CollectionUtils.isEmpty(dayTable)) {
            queryEscalation.setElementIds(dayTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            dayData = elementDataDayMapper.queryEscalation(queryEscalation); //天表数据
        }

        List<DepartmentIndicatorEntity> monthData = new ArrayList<>();
        //todo 新加的，要到日维度查询,天表数据随便查
        if(s1.length() != 10){
            if (!org.springframework.util.CollectionUtils.isEmpty(monthTable)) {
                queryEscalation.setElementIds(monthTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
                monthData = elementDataMonthMapper.queryEscalation(queryEscalation); //月表数据
            }
        }

        Map<String, List<DepartmentIndicatorEntity>> dayMap = dayData.stream().filter(s -> s.getId() != null).collect(Collectors.groupingBy(DepartmentIndicatorEntity::getId));
        Map<String, List<DepartmentIndicatorEntity>> monthMap = monthData.stream().filter(s -> s.getId() != null).collect(Collectors.groupingBy(DepartmentIndicatorEntity::getId));
        dayMap = null == dayMap ? new HashMap<>() : dayMap;
        monthMap = null == monthMap ? new HashMap<>() : monthMap;
        for (IndicatorDataEntity entity : list) {

            //构建EscalationData对象
            EscalationData escalationData = new EscalationData();
            escalationData.setProject(entity.getIndexCode() + entity.getIndexName());
            escalationData.setUnit(entity.getIndexUnit());
            escalationData.setRow(entity.getRank());
            //todo 如果是手填指标，就要查询手填表 不是手填指标才根据公式计算
            //根据ids求出元素表中的元素，然后代入计算公式中解析
            if (StringUtils.isNotBlank(entity.getIds())) {
                //指标的计算公式
                String calculationFormulaId = entity.getCalculationFormulaId();
                List<DepartmentIndicatorEntity> elementDays = new ArrayList<>();
                String[] ids = entity.getIds().split(",");
                for (String id : ids) {
                    if (!org.springframework.util.CollectionUtils.isEmpty(dayMap.get(id))) {
                        List<DepartmentIndicatorEntity> mapValues = dayMap.get(id);
                        elementDays.addAll(mapValues);
                    } else if (!org.springframework.util.CollectionUtils.isEmpty(monthMap.get(id))) {
                        List<DepartmentIndicatorEntity> mapValues = monthMap.get(id);
                        elementDays.addAll(mapValues);
                    }
                }
                CalculatorUtils.calculator(elementDays, calculationFormulaId, escalationData, queryEscalation);
            }
            //如果escalationData.getDynamicColumns() 为空或者长度比queryEscalation.size要短，就补上
            if (escalationData.getDynamicColumns().isEmpty() || escalationData.getDynamicColumns().size() < times.size()) {
                List<String> time = times;
                for (String s : time) {
                    escalationData.getDynamicColumns().putIfAbsent(s, "-");
                }
            }
            BigDecimal temp = BigDecimal.ZERO;
            Map<String, String> dynamicColumns = escalationData.getDynamicColumns();
            if(times.get(0).substring(0,7).equals(times.get(times.size()-1).substring(0,7))){
                String s ;
                for (String key : dynamicColumns.keySet()) {
                    s = dynamicColumns.get(key).equals("-") ? "0" : dynamicColumns.get(key);
                    BigDecimal value = new BigDecimal(s);
                    temp = temp.add(value);
                }
                Map<String, String> averageColumns = new LinkedHashMap<>();
                BigDecimal keysCount = BigDecimal.valueOf(dynamicColumns.size());
                temp = temp.divide(keysCount,4, RoundingMode.HALF_UP);
                //todo key的设置
                averageColumns.put(times.get(0)+"~"+times.get(times.size()-1).substring(5,10), temp.toString());
                escalationData.setDynamicColumns(averageColumns);

            }else{
                Map<String, Double> aggregatedMap = new LinkedHashMap<>();

                for (Map.Entry<String, String> entry : dynamicColumns.entrySet()) {
                    String key = entry.getKey().substring(0, 7);
                    Double value = Double.parseDouble(entry.getValue().equals("-") ? "0" : entry.getValue());
                    if (aggregatedMap.containsKey(key)) {
                        Double sum = aggregatedMap.get(key) + value;
                        aggregatedMap.put(key, sum);
                    } else {
                        aggregatedMap.put(key, value);
                    }
                }

                Map<String, String> averageMap = new LinkedHashMap<>();
                for (Map.Entry<String, Double> entry : aggregatedMap.entrySet()) {
                    String key = entry.getKey();
                    Double sum = entry.getValue();
                    int count1 = dynamicColumns.keySet().stream().filter(k -> k.startsWith(key)).toArray().length;
                    Double average = sum / count1;
                    averageMap.put(key, String.valueOf(average));
                }

                escalationData.setDynamicColumns(averageMap);

            }
            result.add(escalationData);
        }
        return result;
    }

    /**
     * 导出excel
     * @param queryEscalation
     * @param response
     */
    public void export(QueryEscalation queryEscalation, HttpServletResponse response) {
        List<EscalationData> escalationData = queryData(queryEscalation);
        gatherCommonService.dataProcess(escalationData);
        // 导出 Excel todo 应该用范型的，图省事，后面有时间再改
        ExcelUtils.exportExcel(response, escalationData, EscalationData.class, queryEscalation);
    }


}
